﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Twin
{
    public class Constants
    {
        //协议相关常数
        #region 帧头位置（YR-TSEN通信协议v1.00）
        #region 通用帧头
        public const int CH_VER = 0;                    //版本 字节数：1个
        public const int CH_LEN_0 = 1;                  //帧头长度 字节数：2个
        public const int CH_LEN_1 = 2;
        public const int CH_SRC_ADDR_0 = 3;             //源地址 字节数：4个
        public const int CH_SRC_ADDR_1 = 4;
        public const int CH_SRC_ADDR_2 = 5;
        public const int CH_SRC_ADDR_3 = 6;
        public const int CH_OP_TYPE = 7;                //TSEN类型 字节数：1个
        public const int CH_PROPERTY_0 = 8;             //通信属性 字节数：2个
        public const int CH_PROPERTY_1 = 9;
        public const int CH_INST_INDEX_0 = 10;          //指令识别字 字节数：4个
        public const int CH_INST_INDEX_1 = 11;
        public const int CH_INST_INDEX_2 = 12;
        public const int CH_INST_INDEX_3 = 13;
        #endregion

        #region 读当前值带ReadBelt
        public const int CH_DATETIME_0 = 14;            //YMDHmS 字节数：6个
        public const int CH_DATETIME_1 = 15;
        public const int CH_DATETIME_2 = 16;
        public const int CH_DATETIME_3 = 17;
        public const int CH_DATETIME_4 = 18;
        public const int CH_DATETIME_5 = 19;
        public const int CH_FMT_INDEX = 20;             //格式编号 字节数：1个
        public const int CH_READBELT_RESERVED_0 = 21;   //预留字段 字节数：5个
        public const int CH_READBELT_RESERVED_1 = 22;
        public const int CH_READBELT_RESERVED_2 = 23;
        public const int CH_READBELT_RESERVED_3 = 24;
        public const int CH_READBELT_RESERVED_4 = 25;
        #endregion

        #region 读、写映像
        public const int CH_MAP_TYPE = 14;              //区域 字节数：1个
        
        #region 读映像ReadArea
        public const int CH_RESERVED_0 = 15;            //预留字段 字节数：11个
        #endregion
       
        #region 写映像WriteArea
        public const int CH_POST_WRITE = 15;            //Bit0=存储区复位,Bit1=时钟刷新,Bit2=存储区复位方式,Bit3=是否CFG校验 字节数：1个
        #endregion

        public const int CH_RESERVED_1 = 16;
        public const int CH_RESERVED_2 = 17;
        public const int CH_RESERVED_3 = 18;
        public const int CH_RESERVED_4 = 19;
        public const int CH_RESERVED_5 = 20;
        public const int CH_RESERVED_6 = 21;
        public const int CH_RESERVED_7 = 22;
        public const int CH_RESERVED_8 = 23;
        public const int CH_RESERVED_9 = 24;
        public const int CH_RESERVED_10 = 25;
        #endregion
        
        #region 读映像（确认响应）
        public const int CH_STAID_0 = 3;                //终端编码
        public const int CH_STAID_1 = 4;
        public const int CH_STAID_2 = 5;
        public const int CH_STAID_3 = 6;
        #endregion

        #region 通用帧头
        public const int CH_PASSWORD_0 = 26;            //默认 字节数：4个
        public const int CH_PASSWORD_1 = 27;
        public const int CH_PASSWORD_2 = 28;
        public const int CH_PASSWORD_3 = 29;
        public const int CH_HEAD_CRC_0 = 30;            //帧头校验 字节数：2个
        public const int CH_HEAD_CRC_1 = 31;
        public const int CH_LEN_PACK_0 = 32;            //业务包长度 字节数：2个
        public const int CH_LEN_PACK_1 = 33;
        #endregion
        #endregion

        #region 附录v0.05
        //附录A：Property定义
        public const int BIT_INST_DIR = 0;              //指令或应答
        public const int BIT_ANSWER_NEEDED = 1;         //本指令是否需要应答
        public const int BIT_IGNORE_TIME = 2;           //当延时可忽略时（如超短波、直联）时，可忽略时标，使用系统时间作为参数时间坐标
        public const int BIT_CONCATENATED = 3;          //是否级连
        public const int BIT_IF_SINGLE_FRAME = 4;       //是否单帧指令或响应。服务端可据此判断，是否在响应后立即关断连接
        public const int BIT_IF_WAIT = 5;               //是否含WAIT信息
        public const int BIT_BROADCAST = 6;             //是否广播
        //7 预留字段
        public const int BIT_BELTS = 8;                 //业务报文有效
        public const int BIT_PARAS = 9;                 //扩展参数有效
        public const int BIT_XCOM = 10;                 //扩展通信参数有效
        public const int BIT_LOGIN = 11;                //是否进行身份验证
        public const int BIT_DO_CFG_CRC = 12;           //是否含CfgCRC字段
        //13、14 预留字段
        public const int BIT_RET = 15;                  //返回值。与BIT_INST_DIR一起判定指令是否成功。

        //附录B：OpType定义（TSEN）
        public const int OP_READ_BELT = 0x10;           //TER<->SEN
        public const int OP_READ_AREA = 0x11;
        public const int OP_WRITE_AREA = 0x12;
        public const int OP_CLOSE_TRANS = 0x13;

        //附录B：OpType定义（TCOM）
        public const int OP_READ_MSG = 0x21;            //TER<->COM
        public const int OP_TEXT_MSG = 0x22;            //TER<->COM
        public const int OP_MNTE_MSG = 0x23;            //维护MSG，模拟TER
        public const int OP_BASE_MSG = 0x24;            //基础MSG，模拟TER
        public const int OP_SYS_MSG = 0x25;             //系统MSG，仅发送至系统级
        public const int OP_CFG_MSG = 0x26;             //CFG
        public const int OP_ACK = 0x90;
        public const int OP_NAK = 0x91;

        //附录B：OpType定义(TREG)
        public const int OP_GET_STAID = 0x31;           //TER->REG
        public const int OP_GET_REG_STATUS = 0x32;
        public const int OP_UP_AUTHEN = 0x33;
        public const int OP_DOWN_AUTHEN = 0x34;
        /*OP_READ_AREA、OP_WRITE_AREA、OP_ACK、OP_NAK 重复，不再定义*/

        //附录C：MapType定义
        public const int OP_DEFAULT = 0;                //默认，该值为虚拟值，附录中不存在
        public const int OP_CFG = 1;                    //区域。可虚拟设置，如Program可设置在XME内。
        public const int OP_REC = 2;
        public const int OP_XME = 3;
        public const int OP_CALENDAR = 4;
        public const int OP_REMOVABLE = 5;
        public const int OP_PROGRAM = 6;
        public const int OP_PICTURE = 7;
        public const int OP_LOG = 8;                    //日志
        public const int OP_RECORD = 9;                 //从指针起始的记录（反向）
        #endregion

        #region 帧头默认值
        public const int OP_VER = 72;                   //版本　　　　　固定 H
        public const int OP_LEN = 31;                   //帧头长度　　　固定 31
        public const long OP_DES_ADDR = 0xFFFFFFFF;     //目标地址　　　0-0xFFFFFFFE：目标地址  0xFFFFFFFF：传感器忽略目标地址
        public const long OP_SRC_ADDR = 0xFFFFFFFF;     //源地址　　　　现场通信时，不进行源地址验证
        public const int OP_PROPERTY = 5378;            //通信属性　　　详见附录A（0001010000000010）5122
        public const int OP_INST_INDEX = 0;             //指令识别字
        #endregion

        public const int ORDER_MAX_LEN = 0xFFFF;        //报文最大长度

        //协议相关常数
        public const int LEN_HEAD = 32;                 //帧头长度
        public const int LEN_LENPACK = 2;               //业务包长度
        public const int LEN_CRC = 2;                   //正文校验
        public const int LEN_CFG_CRC = 2;               //当MapType=MAP_CFG时，终端根据bitDO_CFG_CRC决定是否需要CFG进行CRC校验;
        public const int LEN_CFG_INDEX =2;              //此时增加CFG_CRC和CfgIndex
        public const int LEN_END = 1;                   //以0结尾
        public const int LEN_SHORT = 32;                //短指令
        public const int PACK_START = 0;                //短指令起始地址
        public const int DATA_START = 32;               //正文起始地址

        //破译位置长度
        public const int POS_C10_C11_C12 = 1;
        public const int LEN_C10_C11_C12 = 1;

        public const int POS_C0 = 1;
        public const int POS_CX = 1;
        public const int LEN_C0 = 1;
        public const int LEN_CX = 1;

        //DataGridView字段定位
        public const int COL_C10_C11_C12_LEN = 1;
        public const int COL_C0_LEN = 1;
        public const int COL_CX_LEN = 1;

        //基元当前行
        public static int jiYuanRowIndex = 0;

        /// <summary>
        /// 指令校验
        /// </summary>
        public static uint GetCrc(byte[] bytes, int start, int length)
        {
            uint sum = 0;
            for (int i = start; i < start + length; i++)
            {
                sum = sum + (uint)(bytes[i]);
            }
            sum = ~sum;
            sum = sum % (256 * 256);
            return sum;
        }

        /// <summary>
        /// 信息校验
        /// </summary>
        public static bool CheckInfo(byte[] bytes, int start, int length)
        {
            try
            {
                //所有字节相加
                long sum1 = 0L;
                long sum2 = 0L;
                for (int i = 0; i <= length - 3; i++)
                {
                    sum1 = sum1 + bytes[start + i];
                }
                //正文校验相加
                sum2 = bytes[start + length - 2] + Convert.ToInt32(bytes[start + length - 1]) * 256;

                if ((sum1 + sum2 + 1) % 65536 == 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 读注册信息
        /// </summary>
        public byte[] ReadRegistrationOrder(int len, byte mapType)
        {
            byte[] inst = new byte[LEN_HEAD];

            inst[CH_VER] = OP_VER;//版本

            byte[] OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN + LEN_LENPACK + len + 2);//帧头长度
            inst[CH_LEN_0] = OP_LEN_BYTES[0];
            inst[CH_LEN_1] = OP_LEN_BYTES[1];

            byte[] OP_SRC_ADDR_BYTES = BitConverter.GetBytes(OP_SRC_ADDR);//源地址
            inst[CH_SRC_ADDR_0] = OP_SRC_ADDR_BYTES[0];
            inst[CH_SRC_ADDR_1] = OP_SRC_ADDR_BYTES[1];
            inst[CH_SRC_ADDR_2] = OP_SRC_ADDR_BYTES[2];
            inst[CH_SRC_ADDR_3] = OP_SRC_ADDR_BYTES[3];

            inst[CH_OP_TYPE] = OP_READ_AREA;//OpType操作类型，读

            byte[] OP_PROPERTY_BYTES = BitConverter.GetBytes(OP_PROPERTY);//Property 通信属性
            inst[CH_PROPERTY_0] = OP_PROPERTY_BYTES[0];
            inst[CH_PROPERTY_1] = OP_PROPERTY_BYTES[1];

            byte[] OP_INST_INDEX_BYTES = BitConverter.GetBytes(OP_INST_INDEX);//指令识别字
            inst[CH_INST_INDEX_0] = OP_INST_INDEX_BYTES[0];
            inst[CH_INST_INDEX_1] = OP_INST_INDEX_BYTES[1];
            inst[CH_INST_INDEX_2] = OP_INST_INDEX_BYTES[2];
            inst[CH_INST_INDEX_3] = OP_INST_INDEX_BYTES[3];

            //附录C：MapType
            if (mapType == Constants.OP_DEFAULT)
            {
                inst[CH_MAP_TYPE] = Constants.OP_CFG;
            }
            else
            {
                inst[CH_MAP_TYPE] = mapType;
            }

            inst[CH_RESERVED_0] = 0;//Reserved 预留字段
            inst[CH_RESERVED_1] = 0;
            inst[CH_RESERVED_2] = 0;
            inst[CH_RESERVED_3] = 0;
            inst[CH_RESERVED_4] = 0;
            inst[CH_RESERVED_5] = 0;
            inst[CH_RESERVED_6] = 0;
            inst[CH_RESERVED_7] = 0;
            inst[CH_RESERVED_8] = 0;
            inst[CH_RESERVED_9] = 0;
            inst[CH_RESERVED_10] = 0;

            inst[CH_PASSWORD_0] = 0;//默认0
            inst[CH_PASSWORD_1] = 0;
            inst[CH_PASSWORD_2] = 0;
            inst[CH_PASSWORD_3] = 0;

            long X = 0L;
            X = GetCrc(inst, 0, LEN_HEAD - 2);//HeadCrc  帧头校验

            byte[] X_BYTES = BitConverter.GetBytes(X);
            inst[CH_HEAD_CRC_0] = X_BYTES[0];
            inst[CH_HEAD_CRC_1] = X_BYTES[1];

            return inst;
        }

        /// <summary>
        /// 写注册信息
        /// </summary>
        public byte[] WriteRegistrationOrder(byte postWrite, int len, byte mapType)
        {
            byte[] inst = new byte[LEN_HEAD];

            inst[CH_VER] = OP_VER;//版本

            byte[] OP_LEN_BYTES;
            if (mapType == Constants.OP_DEFAULT)
            {
                OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN + LEN_LENPACK + len + LEN_CFG_CRC + LEN_CFG_INDEX + LEN_CRC);//帧头长度
            }
            else
            {
                OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN + LEN_LENPACK + len + LEN_CRC);//帧头长度
            }

            inst[CH_LEN_0] = OP_LEN_BYTES[0];
            inst[CH_LEN_1] = OP_LEN_BYTES[1];

            byte[] OP_SRC_ADDR_BYTES = BitConverter.GetBytes(OP_SRC_ADDR);//源地址
            inst[CH_SRC_ADDR_0] = OP_SRC_ADDR_BYTES[0];
            inst[CH_SRC_ADDR_1] = OP_SRC_ADDR_BYTES[1];
            inst[CH_SRC_ADDR_2] = OP_SRC_ADDR_BYTES[2];
            inst[CH_SRC_ADDR_3] = OP_SRC_ADDR_BYTES[3];

            inst[CH_OP_TYPE] = OP_WRITE_AREA;//OpType操作类型，写

            byte[] OP_PROPERTY_BYTES = BitConverter.GetBytes(OP_PROPERTY);//Property 通信属性
            inst[CH_PROPERTY_0] = OP_PROPERTY_BYTES[0];//通信类型
            inst[CH_PROPERTY_1] = OP_PROPERTY_BYTES[1];

            byte[] OP_INST_INDEX_BYTES = BitConverter.GetBytes(OP_INST_INDEX);//指令识别字
            inst[CH_INST_INDEX_0] = OP_INST_INDEX_BYTES[0];
            inst[CH_INST_INDEX_1] = OP_INST_INDEX_BYTES[1];
            inst[CH_INST_INDEX_2] = OP_INST_INDEX_BYTES[2];
            inst[CH_INST_INDEX_3] = OP_INST_INDEX_BYTES[3];

            //附录C：MapType
            if (mapType == Constants.OP_DEFAULT)
            {
                inst[CH_MAP_TYPE] = Constants.OP_CFG;
            }
            else
            {
                inst[CH_MAP_TYPE] = mapType;
            }

            inst[CH_POST_WRITE] = postWrite;//界面上的选项

            inst[CH_RESERVED_1] = 0;//Reserved 预留字段
            inst[CH_RESERVED_2] = 0;
            inst[CH_RESERVED_3] = 0;
            inst[CH_RESERVED_4] = 0;
            inst[CH_RESERVED_5] = 0;
            inst[CH_RESERVED_6] = 0;
            inst[CH_RESERVED_7] = 0;
            inst[CH_RESERVED_8] = 0;
            inst[CH_RESERVED_9] = 0;
            inst[CH_RESERVED_10] = 0;

            inst[CH_PASSWORD_0] = 0;//默认0
            inst[CH_PASSWORD_1] = 0;
            inst[CH_PASSWORD_2] = 0;
            inst[CH_PASSWORD_3] = 0;

            long X = 0L;
            X = GetCrc(inst, 0, LEN_HEAD - 2);//HeadCrc  帧头校验

            byte[] X_BYTES = BitConverter.GetBytes(X);
            inst[CH_HEAD_CRC_0] = X_BYTES[0];
            inst[CH_HEAD_CRC_1] = X_BYTES[1];

            return inst;
        }

        /// <summary>
        /// 读当前值带
        /// </summary>
        public byte[] ReadBeltOrder(byte[] DateTimeBytes, byte FmtIndex)
        {
            byte[] inst = new byte[LEN_HEAD];

            inst[CH_VER] = OP_VER;//版本

            byte[] OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN);//帧头长度
            inst[CH_LEN_0] = OP_LEN_BYTES[0];
            inst[CH_LEN_1] = OP_LEN_BYTES[1];

            byte[] OP_SRC_ADDR_BYTES = BitConverter.GetBytes(OP_SRC_ADDR);//源地址
            inst[CH_SRC_ADDR_0] = OP_SRC_ADDR_BYTES[0];
            inst[CH_SRC_ADDR_1] = OP_SRC_ADDR_BYTES[1];
            inst[CH_SRC_ADDR_2] = OP_SRC_ADDR_BYTES[2];
            inst[CH_SRC_ADDR_3] = OP_SRC_ADDR_BYTES[3];

            inst[CH_OP_TYPE] = OP_READ_BELT;//OpType操作类型，读当前值带

            byte[] OP_PROPERTY_BYTES = BitConverter.GetBytes(OP_PROPERTY);//Property 通信属性
            inst[CH_PROPERTY_0] = OP_PROPERTY_BYTES[0];
            inst[CH_PROPERTY_1] = OP_PROPERTY_BYTES[1];

            byte[] OP_INST_INDEX_BYTES = BitConverter.GetBytes(OP_INST_INDEX);//指令识别字
            inst[CH_INST_INDEX_0] = OP_INST_INDEX_BYTES[0];
            inst[CH_INST_INDEX_1] = OP_INST_INDEX_BYTES[1];
            inst[CH_INST_INDEX_2] = OP_INST_INDEX_BYTES[2];
            inst[CH_INST_INDEX_3] = OP_INST_INDEX_BYTES[3];

            inst[CH_DATETIME_0] = DateTimeBytes[0];//YMDHmS
            inst[CH_DATETIME_1] = DateTimeBytes[1];
            inst[CH_DATETIME_2] = DateTimeBytes[2];
            inst[CH_DATETIME_3] = DateTimeBytes[3];
            inst[CH_DATETIME_4] = DateTimeBytes[4];
            inst[CH_DATETIME_5] = DateTimeBytes[5];

            inst[CH_FMT_INDEX] = FmtIndex;//格式编号

            inst[CH_READBELT_RESERVED_0] = 0;//Reserved 预留字段
            inst[CH_READBELT_RESERVED_1] = 0;
            inst[CH_READBELT_RESERVED_2] = 0;
            inst[CH_READBELT_RESERVED_3] = 0;
            inst[CH_READBELT_RESERVED_4] = 0;

            inst[CH_PASSWORD_0] = 0;//默认0
            inst[CH_PASSWORD_1] = 0;
            inst[CH_PASSWORD_2] = 0;
            inst[CH_PASSWORD_3] = 0;

            long X = 0L;
            X = GetCrc(inst, 0, LEN_HEAD - 2);//HeadCrc 帧头校验

            byte[] X_BYTES = BitConverter.GetBytes(X);
            inst[CH_HEAD_CRC_0] = X_BYTES[0];
            inst[CH_HEAD_CRC_1] = X_BYTES[1];

            return inst;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="DateTimeBytes"></param>
        /// <param name="FmtIndex"></param>
        /// <param name="returnIndex"></param>
        /// <returns></returns>
        public byte[] ReadBeltOrder(byte[] DateTimeBytes, byte FmtIndex, byte returnIndex)
        {
            byte[] inst = new byte[LEN_HEAD];

            inst[CH_VER] = OP_VER;//版本

            byte[] OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN);//帧头长度
            inst[CH_LEN_0] = OP_LEN_BYTES[0];
            inst[CH_LEN_1] = OP_LEN_BYTES[1];

            byte[] OP_SRC_ADDR_BYTES = BitConverter.GetBytes(OP_SRC_ADDR);//源地址
            inst[CH_SRC_ADDR_0] = OP_SRC_ADDR_BYTES[0];
            inst[CH_SRC_ADDR_1] = OP_SRC_ADDR_BYTES[1];
            inst[CH_SRC_ADDR_2] = OP_SRC_ADDR_BYTES[2];
            inst[CH_SRC_ADDR_3] = OP_SRC_ADDR_BYTES[3];

            inst[CH_OP_TYPE] = OP_READ_BELT;//OpType操作类型，读当前值带

            byte[] OP_PROPERTY_BYTES = BitConverter.GetBytes(OP_PROPERTY);//Property 通信属性
            inst[CH_PROPERTY_0] = OP_PROPERTY_BYTES[0];
            inst[CH_PROPERTY_1] = OP_PROPERTY_BYTES[1];

            byte[] OP_INST_INDEX_BYTES = BitConverter.GetBytes(OP_INST_INDEX);//指令识别字
            inst[CH_INST_INDEX_0] = OP_INST_INDEX_BYTES[0];
            inst[CH_INST_INDEX_1] = OP_INST_INDEX_BYTES[1];
            inst[CH_INST_INDEX_2] = OP_INST_INDEX_BYTES[2];
            inst[CH_INST_INDEX_3] = OP_INST_INDEX_BYTES[3];

            inst[CH_DATETIME_0] = DateTimeBytes[0];//YMDHmS
            inst[CH_DATETIME_1] = DateTimeBytes[1];
            inst[CH_DATETIME_2] = DateTimeBytes[2];
            inst[CH_DATETIME_3] = DateTimeBytes[3];
            inst[CH_DATETIME_4] = DateTimeBytes[4];
            inst[CH_DATETIME_5] = DateTimeBytes[5];

            inst[CH_FMT_INDEX] = FmtIndex;//格式编号

            inst[CH_READBELT_RESERVED_0] = returnIndex;//Reserved 预留字段
            inst[CH_READBELT_RESERVED_1] = 0;
            inst[CH_READBELT_RESERVED_2] = 0;
            inst[CH_READBELT_RESERVED_3] = 0;
            inst[CH_READBELT_RESERVED_4] = 0;

            inst[CH_PASSWORD_0] = 0;//默认0
            inst[CH_PASSWORD_1] = 0;
            inst[CH_PASSWORD_2] = 0;
            inst[CH_PASSWORD_3] = 0;

            long X = 0L;
            X = GetCrc(inst, 0, LEN_HEAD - 2);//HeadCrc 帧头校验

            byte[] X_BYTES = BitConverter.GetBytes(X);
            inst[CH_HEAD_CRC_0] = X_BYTES[0];
            inst[CH_HEAD_CRC_1] = X_BYTES[1];

            return inst;
        }


        /// <summary>
        /// 确认响应
        /// </summary>
        public byte[] ReadAnswerOrder(int StaID)
        {
            byte[] inst = new byte[LEN_HEAD];

            inst[CH_VER] = OP_VER;//版本

            byte[] OP_LEN_BYTES = BitConverter.GetBytes(OP_LEN);//帧头长度
            inst[CH_LEN_0] = OP_LEN_BYTES[0];
            inst[CH_LEN_1] = OP_LEN_BYTES[1];

            byte[] StaID_BYTES = BitConverter.GetBytes(StaID);//主机地址
            inst[CH_STAID_0] = StaID_BYTES[0];
            inst[CH_STAID_1] = StaID_BYTES[1];
            inst[CH_STAID_2] = StaID_BYTES[2];
            inst[CH_STAID_3] = StaID_BYTES[3];

            inst[CH_OP_TYPE] = OP_ACK;//OpType操作类型，确认响应

            byte[] OP_PROPERTY_BYTES = BitConverter.GetBytes(1);//Property 通信属性 00000001
            inst[CH_PROPERTY_0] = OP_PROPERTY_BYTES[0];//通信类型
            inst[CH_PROPERTY_1] = OP_PROPERTY_BYTES[1];

            inst[10] = 0;//Reserved 预留字段
            inst[11] = 0;
            inst[12] = 0;
            inst[13] = 0;
            inst[14] = 0;
            inst[15] = 0;
            inst[16] = 0;
            inst[17] = 0;
            inst[18] = 0;
            inst[19] = 0;
            inst[20] = 0;
            inst[21] = 0;
            inst[22] = 0;
            inst[23] = 0;
            inst[24] = 0;
            inst[25] = 0;
            inst[26] = 0;
            inst[27] = 0;
            inst[28] = 0;
            inst[29] = 0;

            long X = 0L;
            X = GetCrc(inst, 0, LEN_HEAD - 2);//HeadCrc  帧头校验

            byte[] X_BYTES = BitConverter.GetBytes(X);
            inst[CH_HEAD_CRC_0] = X_BYTES[0];
            inst[CH_HEAD_CRC_1] = X_BYTES[1];

            return inst;
        }
    }
}